package com.ckzp.core.util;

import cn.hutool.core.img.Img;
import cn.hutool.core.io.FileUtil;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;

/**
 * Created by 51594 on 2022/7/28.
 */
public class ImageUtil {


    /**
     * 检查是否指定宽高
     *
     * @param path
     * @param width
     * @param height
     * @return
     */
    public static boolean checkImageWidthHeight(String path, int width, int height) {
        try {
            BufferedImage bufferedImage = ImageIO.read(new File(path));
            int widths = bufferedImage.getWidth();
            int heights = bufferedImage.getHeight();
            if (width == widths && height == heights) {
                return true;
            }
        } catch (IOException e) {
            //e.printStackTrace();
        }
        return false;
    }


    /**
     * 检查是否指定宽高
     *
     * @param path
     * @param size
     * @return
     */
    public static boolean checkImageSize(String path, long size) {
        try {
            File file = new File(path);
            if (file.length() < size) {
                return true;
            }
        } catch (Exception e) {
            //e.printStackTrace();
        }
        return false;
    }

    /**
     * 取得图片宽高
     *
     * @param path
     * @return
     */
    public static String getImageWidthHeight(String path) {
        try {
            BufferedImage bufferedImage = ImageIO.read(new File(path));
            int widths = bufferedImage.getWidth();
            int heights = bufferedImage.getHeight();
            return "[" + widths + "," + heights + "]";
        } catch (IOException e) {
            //e.printStackTrace();
        }
        return "[]";
    }

    /**
     * @param oldname
     * @return
     */
    public static String getFileRename(String oldname) {
        int index = oldname.lastIndexOf(".");
        String ext = oldname.substring(index, oldname.length());
        if (ext != null) ext = ext.toLowerCase();
        long filename = DateUtil.getDate().getTime();
        return filename + ext;
    }

    /**
     * @param oldname
     * @return
     */
    public static String getFileTagRename(String oldname, String tag) {
        int index = oldname.lastIndexOf(".");
        String ext = oldname.substring(index, oldname.length());
        if (ext != null) ext = ext.toLowerCase();
        long filename = DateUtil.getDate().getTime();
        return filename + "_" + tag + ext;
    }

    /**
     * @param oldname
     * @return
     */
    public static String getFileRename(String oldname, long newlongs) {
        int index = oldname.lastIndexOf(".");
        String ext = oldname.substring(index, oldname.length());
        if (ext.indexOf(".png") > -1) ext = ".png";
        if (ext.indexOf(".jpg") > -1) ext = ".jpg";
        if (ext.indexOf(".gif") > -1) ext = ".gif";
        if (ext != null) ext = ext.toLowerCase();
        return newlongs + ext;
    }

    /**
     * 保存base64图片
     *
     * @param basestr
     * @param savepath
     */
    public void saveBase64Image(String basestr, String savepath) {
        String ext = "data:image/jpg;base64";
        basestr = basestr.split(",")[1];//去掉base64码的data:image/png;base64,
        BASE64Decoder decoder = new BASE64Decoder();
        OutputStream out = null;
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(basestr);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            // 生成jpeg图片
            out = new FileOutputStream(savepath);
            out.write(bytes);
            out.flush();
            out.close();
        } catch (Exception e) {
        } finally {
            try {
                if (out != null) out.close();
            } catch (Exception e) {

            }
        }
    }


    /**
     * 图片加工方法
     * <p/>
     * 支持的图片格式: BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif
     *
     * @param imgUrl       目标文件的地址
     * @param outputStream 输出流
     * @param width        图片裁剪后的宽度
     * @param height       图片裁剪后的高度
     * @throws IOException
     */
    public static void imageProcess(String imgUrl, ByteArrayOutputStream outputStream,
                                    int width, int height) throws IOException {
        byte[] imgBytes = getImgBytes(imgUrl);
        InputStream pojoInputStream = new ByteArrayInputStream(imgBytes);
        InputStream readInputStream = new ByteArrayInputStream(imgBytes);
        {
            // 图片对象
            BufferedImage bufferedImage = ImageIO.read(pojoInputStream);
            // 高度
            float imgWidth = Float.parseFloat(String.valueOf(bufferedImage.getWidth()));
            float imgHeight = Float.parseFloat(String.valueOf(bufferedImage.getHeight()));
            // 缩放比例
            float scale = 1;
            if (width > 0 && height > 0) {
                scale = 1 / (imgHeight / height);
            } else if (width > 0 && height == 0) {
                scale = 1 / (imgWidth / width);
                height = Math.round(scale * imgHeight);
            } else if (height > 0 && width == 0) {
                scale = 1 / (imgHeight / height);
                width = Math.round(scale * imgWidth);
            } else {
                width = Math.round(imgWidth);
                height = Math.round(imgHeight);
            }

            // 矩形对象
            Rectangle rectangle = new Rectangle(0, 0, width, height);

            Img.from(readInputStream)    // 读文件
                    .scale(scale)        // 压缩
                    .cut(rectangle)      // 裁剪
                    .write(outputStream);// 写文件
        }
    }

    /**
     * 获取文件二进制数据
     *
     * @param imgUrl 图片地址
     * @return 二进制数据
     * @throws IOException
     */
    public static byte[] getImgBytes(String imgUrl) throws IOException {
        InputStream inputStream = getImgInputStream(imgUrl);
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        {
            int rc;
            byte[] buff = new byte[100];
            while ((rc = inputStream.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            return swapStream.toByteArray();
        }
    }

    /**
     * 获取文件输入流
     *
     * @param imgUrl 图片地址
     * @return 输入流
     * @throws IOException
     */
    public static InputStream getImgInputStream(String imgUrl) throws IOException {
        InputStream inputStream;
        try {
            // 网络图片
            URL url = new URL(imgUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            inputStream = connection.getInputStream();
        } catch (Exception urlException) {
            // 本地图片
            File file = FileUtil.file(imgUrl);
            inputStream = Files.newInputStream(file.toPath());
        }
        return inputStream;
    }

    /**
     * 重置图片大小
     *
     * @param imgUrl 原图
     * @param outUrl 保存位置
     * @param width  宽度 0为按高度比例来
     * @param height 高度 0 为接宽度比例来
     */
    public static boolean resizeImage(String imgUrl, String outUrl, int width, int height) {
        try {
            ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
            OutputStream outputStream = Files.newOutputStream(new File(outUrl).toPath());
            ImageUtil.imageProcess(imgUrl, arrayOutputStream, width, height);
            arrayOutputStream.writeTo(outputStream);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] arg) {
        resizeImage("d:/1.png", "d:/2.png", 800, 500);
    }
}
